package com.b.interceptor;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import com.b.domain.Admin;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.web.servlet.HandlerInterceptor;

import com.b.domain.User;
import com.b.utils.JwtUtil;
import com.b.vo.Result;
import com.fasterxml.jackson.databind.ObjectMapper;

import io.jsonwebtoken.Claims;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

public class JwtInterceptor implements HandlerInterceptor {

    private final StringRedisTemplate stringRedisTemplate;

    public JwtInterceptor(StringRedisTemplate stringRedisTemplate) {
        this.stringRedisTemplate = stringRedisTemplate;
    }

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        String token = request.getHeader("token");
//        System.out.println("token = " + token);

        // 验证token有效性
        Result result = validateToken(token);
        if (result.getCode().equals("200")) {
            return true; // 验证通过，继续执行请求
        } else {
            // 验证失败，返回错误信息
            sendJsonResponse(response, result);
            return false;
        }
    }

    private Result validateToken(String token) {
        Result result = new Result();
        
        if (token == null || token.isEmpty()) {
            return result.setCode("503").setMsg("缺少token");
        }
        
        // 验证token有效性
        boolean isValid = JwtUtil.validJwt(token);
        if (isValid) {
            Claims claims = JwtUtil.parseJwt(token);
            try {
                // 先获取 LinkedHashMap 形式的 admin 数据
                Map<String, Object> adminMap = (Map<String, Object>) claims.get("admin");
                // 使用 ObjectMapper 将 Map 转换为 Admin 对象
                ObjectMapper objectMapper = new ObjectMapper();
                Admin admin = objectMapper.convertValue(adminMap, Admin.class);
                
                ValueOperations<String, String> ops = stringRedisTemplate.opsForValue();
                String adminKey = "admin:" + admin.getId();
                String storedToken = ops.get(adminKey);
                
                if (storedToken != null) {
                    // 检查token是否匹配（可选）
                    if (!storedToken.equals(token)) {
                        return result.setCode("504").setMsg("无效的token");
                    }
                    
                    // 自动续期逻辑
                    Long expire = stringRedisTemplate.getExpire(adminKey, TimeUnit.MINUTES);
                    if (expire != null && expire < 5) {
                        stringRedisTemplate.expire(adminKey, expire + 30, TimeUnit.MINUTES);
                    }
                    
                    return result.setCode("200").setMsg("正常");
                } else {
                    return result.setCode("501").setMsg("会话过期,需要重新登录");
                }
            } catch (Exception e) {
                System.out.println(e);
                return result.setCode("505").setMsg("解析token失败");
            }
        } else {
            return result.setCode("502").setMsg("无效的token签名");
        }
    }

    private void sendJsonResponse(HttpServletResponse response, Result result) throws IOException {
        response.setContentType("application/json;charset=UTF-8");
        try (PrintWriter writer = response.getWriter()) {
            // 这里需要将Result对象转换为JSON字符串
            // 实际项目中可以使用Jackson或其他JSON工具
            writer.write("{\"code\":\"" + result.getCode() + "\",\"mgs\":\"" + result.getMsg() + "\"}");
        }
    }
}    